import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/controller/evaluation.dart';
import 'package:ichinesereader/models/common/LevelOption.dart';
import 'package:ichinesereader/models/evaluation/skillPointsResult.dart';
import 'package:ichinesereader/utils/helper.dart';
import 'package:ichinesereader/utils/log.dart';
import 'package:syncfusion_flutter_treemap/treemap.dart';

class EvaluationLanguageSkillsDetails extends StatefulWidget {
  @override
  _EvaluationLanguageSkillsDetailsState createState() =>
      _EvaluationLanguageSkillsDetailsState();
}

class _EvaluationLanguageSkillsDetailsState
    extends State<EvaluationLanguageSkillsDetails>
    with SingleTickerProviderStateMixin {
  final box = Hive.box('appconfig');
  final EvaluationController controller = Get.find();
  String _classId = '';
  String _currentLevel = '';
  late Map<String, Color> _colors;
  late List<SkillPointsDataTree> _totalTreeData;
  late List<TreemapLevel> _treemapLevels;
  late AnimationController _opacityAnimationController;
  late Animation<double> _opacityAnimation;
  bool isTeacher = false;

  @override
  void initState() {
    isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
        Constants.NanhaiRole_Teacher;
    if (isTeacher) {
      _classId = box.get(CacheManagerKey['currentclass'].toString());
    } else {
      _classId = '';
    }

    try {
      if (isTeacher) {
        _currentLevel =
            (box.get(CacheManagerKey['eveluationlevel'].toString()) as double)
                .toInt()
                .toString();
      } else {
        _currentLevel = int.tryParse(
                box.get("UserLevel").toString().replaceAll('level', ''))
            .toString();
      }
    } catch (error) {
      box.put(CacheManagerKey['eveluationlevel'].toString(), 1);
      _currentLevel = '1';
    }
    Future.delayed(Duration(milliseconds: 200), () {
      controller.fetchEvaluationSkillPointsData(_classId, _currentLevel);
    });

    _treemapLevels = [];
    _totalTreeData = [];
    _colors = <String, Color>{
      'Listening': hexStringToHexInt(Constants.evaluationSkillTypes
          .where((element) => element.skill == 'Listening')
          .first
          .color
          .toString()),
      'Reading': hexStringToHexInt(Constants.evaluationSkillTypes
          .where((element) => element.skill == 'Reading')
          .first
          .color
          .toString()),
    };

    _opacityAnimationController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 1000));
    _opacityAnimation = CurvedAnimation(
        parent: _opacityAnimationController, curve: Curves.linear);

    super.initState();
  }

  @override
  void dispose() {
    _opacityAnimationController.dispose();
    _treemapLevels.clear();
    _totalTreeData.clear();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Log.debug('build teacher/student evaluation language skills points page');
    return Scaffold(
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        primary: false,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Center(
            child: Column(
              children: [
                Wrap(
                  children: [
                    FormBuilderChoiceChip(
                      alignment: WrapAlignment.start,
                      labelPadding: EdgeInsets.fromLTRB(5, 0, 5, 0),
                      selectedColor: Get.theme.primaryColor,
                      backgroundColor: Colors.transparent,
                      initialValue: Constants.levelEvaluationOptions
                          .where((element) =>
                              element.value
                                  .toString()
                                  .replaceAll('level', '') ==
                              _currentLevel.toString())
                          .first,
                      //elevation: 0.5,
                      decoration: InputDecoration(
                        labelText: 'Levels',
                        labelStyle: Get.theme.textTheme.labelSmall,
                        border: InputBorder.none,
                      ),
                      name: 'level_filter_chip',
                      onChanged: (value) {
                        if (value == null) return;
                        var item = value as LevelOption;
                        _currentLevel =
                            item.value.toString().replaceAll('level', '');
                        controller.fetchEvaluationSkillPointsData(
                            _classId, _currentLevel);
                      },
                      options: Constants.levelEvaluationOptions
                          .map((level) => FormBuilderChipOption<LevelOption>(
                                value: level,
                                child: Text(
                                  level.label
                                      .toString()
                                      .replaceAll('Level 0', 'N/A')
                                      .replaceAll('Level ', ''),
                                  style: TextStyle(
                                    fontSize: 15,
                                    fontWeight: FontWeight.bold,
                                    color: hexStringToHexInt(
                                        level.color.toString()),
                                    letterSpacing: 0,
                                  ),
                                ),
                              ))
                          .toList(),
                    ),
                  ],
                ),
                // Visibility(
                //     visible: isTeacher,
                //     child: Row(
                //       mainAxisAlignment: MainAxisAlignment.end,
                //       children: [
                //         Container(
                //             height: 48,
                //             width: 240,
                //             child: FormBuilderChoiceChip(
                //               decoration: InputDecoration.collapsed(
                //                 hintText: '',
                //                 border: InputBorder.none,
                //               ),
                //               spacing: 8,

                //               labelStyle: TextStyle(
                //                 color: Theme.of(context).primaryColorLight,
                //                 fontSize: 15,
                //                 letterSpacing: 0.8,
                //               ),
                //               backgroundColor: Get.theme.primaryColor,
                //               selectedColor: Get.isDarkMode
                //                   ? (Colors.white)
                //                   : Theme.of(context).primaryColorDark,
                //               name: 'level_standard_types',
                //               onChanged: (value) {
                //                 if (value == null) return;
                //               },
                //               initialValue: Constants.levelStandardTypes[0],

                //               ///这里暂时去掉yct
                //               options: Constants.levelStandardTypes
                //                   .where((element) => element != 'YCT')
                //                   .map((state) => FormBuilderChipOption<String>(
                //                         value: state,
                //                         child: Text(
                //                           state.toString(),
                //                         ),
                //                       ))
                //                   .toList(),
                //             )),
                //       ],
                //     )),
                Container(
                  height: isTeacher ? Get.height - 150 : Get.height - 300,
                  child: controller.obx(
                    (data) {
                      _totalTreeData = [];
                      if (controller.evaluationSkillPointsDataTree.isNotEmpty) {
                        var dataTree = controller.evaluationSkillPointsDataTree;
                        _buildTotalDatatree(dataTree, '', '');
                        _totalTreeData.removeWhere((element) =>
                                element.skills != null &&
                                element.skills!.length > 0
                            // element.parentId == null ||
                            // element.parentId == '202'
                            );
                        _treemapLevels = _getTreemapLevels();
                      }
                      if (_totalTreeData.length > 0) {
                        return SfTreemap(
                          dataCount: _totalTreeData.length,
                          weightValueMapper: (int index) {
                            return 1;
                          },
                          enableDrilldown: true,
                          breadcrumbs: TreemapBreadcrumbs(
                            builder: (BuildContext context, TreemapTile tile,
                                bool isCurrent) {
                              final String breadcrumbText =
                                  tile.group == 'Home' ? 'Skills' : tile.group;
                              final Widget current = AnimatedDefaultTextStyle(
                                style: Theme.of(context)
                                    .textTheme
                                    .bodySmall!
                                    .copyWith(
                                        color: !Get.isDarkMode
                                            ? const Color.fromRGBO(
                                                10, 10, 10, 1)
                                            : const Color.fromRGBO(
                                                255, 255, 255, 1),
                                        fontWeight:
                                            isCurrent && tile.group != 'Home'
                                                ? FontWeight.bold
                                                : FontWeight.normal),
                                duration: const Duration(milliseconds: 500),
                                child: Text(breadcrumbText),
                              );

                              if (tile.group == 'Home') {
                                if (!isCurrent) {
                                  _opacityAnimationController.forward();
                                } else {
                                  _opacityAnimationController.reverse();
                                }
                                return FadeTransition(
                                    opacity: _opacityAnimation, child: current);
                              }
                              return current;
                            },
                          ),
                          tooltipSettings: TreemapTooltipSettings(
                            color: !Get.isDarkMode
                                ? const Color.fromRGBO(45, 45, 45, 1)
                                : const Color.fromRGBO(242, 242, 242, 1),
                          ),
                          levels: _treemapLevels,
                        );
                      } else {
                        return Visibility(child: Text(''), visible: false);
                      }
                    },
                    onEmpty: Text('Data not available ...'.tr),
                    // onLoading: Center(
                    //     child: CircularProgressIndicator(
                    //   backgroundColor: Get.theme.primaryColorDark,
                    //   strokeWidth: 9.0,
                    // )),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  _buildTotalDatatree(
      List<SkillPointsDataTree> inDatatree, String? _parentId, String _type) {
    if (inDatatree.isNotEmpty) {
      inDatatree.forEach((tree) {
        if (_totalTreeData.where((element) => element.id == tree.id).isEmpty) {
          if (_type == '') {
            tree.type = tree.name;
          } else {
            tree.type = _type;
          }
          if (_parentId != null && _parentId != '' && tree.parentId == null)
            tree.parentId = _parentId;

          if (tree.id != null && tree.id != '201' && tree.id != '202')
            _totalTreeData.add(tree);
        }
        if (tree.skills != null && tree.skills!.length > 0) {
          _buildTotalDatatree(tree.skills as List<SkillPointsDataTree>, tree.id,
              tree.type.toString());
        }
      });
    }
  }

  List<TreemapLevel> _getTreemapLevels() {
    return <TreemapLevel>[
      TreemapLevel(
        groupMapper: (int index) => _totalTreeData[index].type,
        colorValueMapper: (TreemapTile tile) {
          return _colors[_totalTreeData[tile.indices[0]].type];
        },
        //color: Get.theme.scaffoldBackgroundColor,
        labelBuilder: (BuildContext context, TreemapTile tile) {
          return _buildParentTileLabels(tile);
        },
        itemBuilder: (BuildContext context, TreemapTile tile) {
          return _buildItemBuilder(tile);
        },
      ),
      TreemapLevel(
        groupMapper: (int index) => _totalTreeData[index].parentId,
        // colorValueMapper: (TreemapTile tile) {
        //   return _colors[dataTreeList[tile.indices[0]].name];
        // },
        //color: Get.theme.scaffoldBackgroundColor,
        tooltipBuilder: (BuildContext context, TreemapTile tile) {
          return _buildTooltipBuilder(tile);
        },
        labelBuilder: (BuildContext context, TreemapTile tile) {
          return _buildDescendantsLabels(tile);
        },
        itemBuilder: (BuildContext context, TreemapTile tile) {
          return _buildItemBuilder(tile);
        },
      ),
      TreemapLevel(
        groupMapper: (int index) => _totalTreeData[index].id,
        tooltipBuilder: (BuildContext context, TreemapTile tile) {
          return _buildTooltipBuilder(tile);
        },
        labelBuilder: (BuildContext context, TreemapTile tile) {
          return _buildDescendantsLabels(tile);
        },
        itemBuilder: (BuildContext context, TreemapTile tile) {
          return _buildItemBuilder(tile);
        },
      ),
    ];
  }

  Widget _buildParentTileLabels(TreemapTile tile) {
    final Brightness brightness =
        ThemeData.estimateBrightnessForColor(tile.color);
    final Color color =
        brightness == Brightness.dark ? Colors.white : Colors.black;
    return Stack(
      children: <Widget>[
        Align(
          alignment: Alignment.topLeft,
          child: Padding(
            padding: const EdgeInsets.only(left: 4, top: 4, right: 4),
            child: Text(
              tile.group,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: color,
                fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize,
              ),
            ),
          ),
        ),
        Align(
          alignment: Alignment.bottomLeft,
          child: Padding(
            padding: const EdgeInsets.all(4),
            child: Text(
              tile.group,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: color,
                fontSize: Theme.of(context).textTheme.bodySmall!.fontSize,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildDescendantsLabels(TreemapTile tile) {
    var _currentTree = SkillPointsDataTree();
    int type = _treemapLevels.indexOf(tile.level);
    if (type == 0)
      _currentTree =
          _totalTreeData.where((element) => element.name == tile.group).first;
    if (type == 1)
      _currentTree = _totalTreeData
          .where((element) => element.parentId == tile.group)
          .first;
    if (type == 2)
      _currentTree =
          _totalTreeData.where((element) => element.id == tile.group).first;

    final Brightness brightness =
        ThemeData.estimateBrightnessForColor(tile.color);
    final Color color =
        brightness == Brightness.dark ? Colors.white : Colors.black;
    return Center(
      child: Padding(
        padding: const EdgeInsets.only(left: 4.0, top: 4.0, right: 4),
        child: Text(
          _currentTree.name.toString(),
          style: Theme.of(context)
              .textTheme
              .bodySmall!
              .copyWith(fontSize: 11, color: color),
          overflow: TextOverflow.ellipsis,
        ),
      ),
    );
  }

  Widget _buildItemBuilder(TreemapTile tile) {
    if (tile.hasDescendants) {
      return Padding(
        padding: EdgeInsets.only(right: 4, bottom: 4),
        child: Align(
          alignment: Alignment.bottomRight,
          child: Icon(
            Icons.add_circle_outline,
            size: 20,
            color: Get.isDarkMode
                ? const Color.fromRGBO(255, 255, 255, 1)
                : const Color.fromRGBO(10, 10, 10, 1),
          ),
        ),
      );
    } else {
      return const SizedBox();
    }
  }

  Widget _buildTooltipBuilder(TreemapTile tile) {
    var _currentTree = SkillPointsDataTree();
    int type = _treemapLevels.indexOf(tile.level);
    if (type == 0)
      _currentTree =
          _totalTreeData.where((element) => element.name == tile.group).first;
    if (type == 1)
      _currentTree = _totalTreeData
          .where((element) => element.parentId == tile.group)
          .first;
    if (type == 2)
      _currentTree =
          _totalTreeData.where((element) => element.id == tile.group).first;

    if (_currentTree.id != null) {
      return Padding(
        padding: const EdgeInsets.fromLTRB(10.0, 7.0, 10.0, 8.5),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            // SizedBox(
            //   child: RichText(
            //     text: TextSpan(
            //       text: _treemapLevels.indexOf(tile.level) == 1
            //           ? 'Skill'
            //           : 'Skill',
            //       style: Theme.of(context).textTheme.bodySmall!.copyWith(
            //             height: 1.5,
            //             color: !Get.isDarkMode
            //                 ? const Color.fromRGBO(255, 255, 255, 0.75)
            //                 : const Color.fromRGBO(10, 10, 10, 0.75),
            //           ),
            //       children: <TextSpan>[
            //         TextSpan(text: '\n ${_currentTree.name}')
            //       ],
            //     ),
            //   ),
            // ),
            // const SizedBox(width: 15.0),
            SizedBox(
              child: RichText(
                text: TextSpan(
                  text: _currentTree.name,
                  style: Theme.of(context).textTheme.bodySmall!.copyWith(
                        height: 1.5,
                        fontWeight: FontWeight.bold,
                        overflow: TextOverflow.ellipsis,
                        color: !Get.isDarkMode
                            ? const Color.fromRGBO(255, 255, 255, 1)
                            : const Color.fromRGBO(10, 10, 10, 1),
                      ),
                  children: <TextSpan>[
                    TextSpan(
                        text:
                            '\nCorrect: ${_currentTree.correct} \nTotal: ${_currentTree.total}'),
                  ],
                ),
              ),
            )
          ],
        ),
      );
    } else {
      return Text('');
    }
  }
}
